<?php
/**
 * Products model
 * 
 * @author Konstantin Shamko <konstantin.shamko@gmail.com> 
 * @version 0.0.1
 * @copyright  Copyright (c) 2009 Konstantin Shamko
 * @package Products Module
 * @license  New BSD License
 *
 */
class Models_Products extends Bel_Model_Abstract {
	
	/**
	 * Array of tables' classes which are in one-to-many relation with products table.  
	 *
	 * @var array
	 */
	protected $_dependentTables = array('Models_Products_Images','Models_Products_AttributeValues','Models_Products_Categories');
	
	/**
	 * Describes many-to-one relation between products and products' templates
	 *
	 * @var array
	 */
	protected $_referenceMap = array (
								'Template' => array (
									'columns' => 'product_template_id',
									'refTableClass' => 'Models_ProductTemplates',
									'refColumns' => 'product_template_id', 
									'onDelete' => self::CASCADE	)
								);	
	
	/**
	 * Sets products table name and primary key
	 *
	 * @return void
	 */								
	public function __construct() {
		$this->_name = TABLE_PREFIX . "products";
		$this->_primary = array('product_id');
		parent::__construct ();
	}

	/**
	 * Adds product and its attributes values
	 *
	 * @param array $data_to_add - associative array (key - name of a table field, value - field value) 
	 * @return int - last inserted entry primary key
	 */
	public function addEntry($data_to_add){
		$product_id = parent::addEntry($data_to_add);
		
		$oProdAttrValue = new Models_Products_AttributeValues();
		$oProdAttrValue->addValuesForProduct($product_id, $data_to_add['attr']);
		
		return $product_id;
	}
	
	/**
	 * Returns product and its attributes values by id
	 *
	 * @param int $id - product id value
	 * @return array - product data
	 */	
	public function getEntryById($id){
		$oVals = new Models_Products_AttributeValues();
		$select = $this->_db->select()->from(array('p'=>$this->_name))->joinLeft(array('v'=>$oVals->info('name')),'v.product_id=p.product_id')->where('p.product_id=\''.$id.'\'');
		$result = $this->_db->query($select)->fetchAll();
		
		$product = array();
		$cols = $this->info('cols');
		foreach ($cols as $field){
			$product[$field] = $result[0]->$field;
		}
		
		foreach ($result as $val){
			$product['attr['.$val->template_attribute_id.']'] = $val->product_attribute_value;
		}
		
		return $product;
	}
	
	/**
	 * Returns full product (product date, product attributes' values, product images, product categories)
	 *
	 * @param int $product_id
	 * @return array - full product info
	 */
	public function getFullProductInfo($product_id){
		$product = $this->find($product_id)->current();
		
		if($product){		
			$oAttrValues = new Models_Products_AttributeValues();	
			$productAttributes = $oAttrValues->getAttributesByProduct($product_id);
			$productImages = $product->findDependentRowset('Models_Products_Images',null,$this->select()->order('is_main DESC'));
			$productCategories = $product->findManyToManyRowset('Models_ProductCategories','Models_Products_Categories');
			return array('product'=>$product->toArray(),'attributes'=>$productAttributes,'images'=>$productImages->toArray(),'categories'=>$productCategories->toArray());
		}else{
			return false;
		}
	}
	
	/**
	 * Updates product and its attributes values
	 *
	 * @param array $data_to_update - associative array (key - name of a table field, value - field value) 
	 * @return int - number of affected rows
	 */
	public function updateEntry($data_to_update) {
		$res = parent::updateEntry($data_to_update);		
		$oProdAttrValue = new Models_Products_AttributeValues();
		$oProdAttrValue->updateValuesForProduct($data_to_update['product_id'], $data_to_update['attr']);		
		return $res;		
	}
	
	/**
	 * Returns product by categories. Return data contains general product info (with no attributes) and images info
	 *
	 * @param int $cat_id - category id
	 * @param array||string $order - sort params
	 * @param int $page - number of page to select
	 * @return array - array of stdObjects
	 */
	public function getProductsByCategory($cat_id,$order=null,$page=1){
		$this->setSelectMethod('_selectQueryByCategory');
		return parent::getAll('category_id=\''.$cat_id.'\'',$order,$page);
	}
	
	/**
	 * Prepares select query for getAll method. This select will return products with images 
	 *
	 * @return Zend_Db_Select
	 */
	protected function _selectQueryByCategory(){
		$oProd2Cat = new Models_Products_Categories();
		$oProdImg = new Models_Products_Images();
		$select = $this->_db
			->select()
			->from($this->_name)
			->joinInner(array('p2c'=>$oProd2Cat->info('name')),$this->_name.'.product_id=p2c.product_id')			
			->joinLeft(array('img'=>$oProdImg->info('name')),$this->_name.'.product_id=img.product_id and img.is_main=1',array('is_main','image_title','image_filename'));		

		return $select;	
	} 

	/**
	 * Prepares select query for getAll method. This select will return products with templates 
	 *
	 * @return Zend_Db_Select
	 */
	protected function _selectQuery(){
		$select = parent::_selectQuery();
		$oTemplates = new Models_ProductTemplates();
		$select->joinLeft(array('t'=>$oTemplates->info('name')),'t.product_template_id='.$this->_name.'.product_template_id');
		return $select;
	}
	
}